package tech.xs.sys.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import tech.xs.common.framework.domain.annotations.AuthApi;
import tech.xs.common.framework.domain.model.ApiResult;
import tech.xs.common.framework.util.BaseEntityUtil;
import tech.xs.common.sys.domain.constant.PermissionConstant;
import tech.xs.common.util.SyncUtil;
import tech.xs.sys.domain.bo.web.menu.show.ListAllWebMenuShowBo;
import tech.xs.sys.domain.bo.web.menu.show.UpdateRoleWebMenuBo;
import tech.xs.sys.domain.entity.SysRole;
import tech.xs.sys.domain.entity.SysWebMenuShow;
import tech.xs.sys.domain.enums.SysWebMenuShowType;
import tech.xs.sys.service.SysRoleService;
import tech.xs.sys.service.SysWebMenuShowService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Validated
@RestController
@RequestMapping("/web/menu/show")
public class SysWebMenuShowController {

    @Resource
    private SysWebMenuShowService sysWebMenuShowService;
    @Resource
    private SysRoleService sysRoleService;


    @GetMapping("/list/all")
    @AuthApi(permissions = PermissionConstant.ROLE_MGR)
    public ApiResult<List<SysWebMenuShow>> listAll(@ModelAttribute ListAllWebMenuShowBo bo) {
        return ApiResult.success(sysWebMenuShowService.list(Wrappers.<SysWebMenuShow>lambdaQuery()
                .eq(bo.getShowType() != null, SysWebMenuShow::getShowType, bo.getShowType())
                .eq(StrUtil.isNotBlank(bo.getRoleCode()), SysWebMenuShow::getRoleCode, bo.getRoleCode())
        ));
    }

    @PostMapping("/updateRoleMenu")
    @AuthApi(permissions = PermissionConstant.ROLE_MGR)
    public ApiResult<Void> updateRoleMenu(@Validated @RequestBody UpdateRoleWebMenuBo bo) {
        long roleCount = sysRoleService.count(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getCode, bo.getRoleCode()));
        if (roleCount <= 0) {
            return ApiResult.error("角色不存在");
        }
        List<SysWebMenuShow> sourceList = new ArrayList<>();
        List<String> menuCodes = bo.getMenuCodes();
        for (String menuCode : menuCodes) {
            SysWebMenuShow item = new SysWebMenuShow();
            item.setWebMenuCode(menuCode);
            item.setRoleCode(bo.getRoleCode());
            item.setShowType(SysWebMenuShowType.ROLE);
            sourceList.add(item);
        }

        List<SysWebMenuShow> dbList = sysWebMenuShowService.list(Wrappers.<SysWebMenuShow>lambdaQuery()
                .eq(SysWebMenuShow::getRoleCode, bo.getRoleCode())
                .eq(SysWebMenuShow::getShowType, SysWebMenuShowType.ROLE)
        );
        List<SysWebMenuShow> addList = new ArrayList<>();
        List<SysWebMenuShow> updateList = new ArrayList<>();
        List<SysWebMenuShow> deleteList = new ArrayList<>();
        SyncUtil.contrast(sourceList, dbList, addList, updateList, deleteList, new SyncUtil.Compare<SysWebMenuShow>() {
            @Override
            public boolean compare(SysWebMenuShow o1, SysWebMenuShow o2) {
                return o1.getRoleCode().equals(o2.getRoleCode())
                        && o1.getWebMenuCode().equals(o2.getWebMenuCode())
                        && o1.getShowType().equals(o2.getShowType());
            }

            @Override
            public SysWebMenuShow sourceToTarget(SysWebMenuShow source, SysWebMenuShow target) {
                source.setId(target.getId());
                return source;
            }
        });

        log.info("更新或保存角色菜单 addList:" + addList + " updateList:" + updateList + " deleteList:" + deleteList);
        if (!updateList.isEmpty()) {
            sysWebMenuShowService.updateBatchById(updateList, 300);
        }
        if (!deleteList.isEmpty()) {
            sysWebMenuShowService.removeBatchByIds(BaseEntityUtil.toIdList(deleteList), 300);
        }
        if (!addList.isEmpty()) {
            sysWebMenuShowService.saveBatch(addList, 300);
        }

        return ApiResult.success();
    }


}
